package com.atguigu.spzx.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.cart.service.CartService;
import com.atguigu.spzx.common.util.AuthContextUtil;
import com.atguigu.spzx.feign.product.ProductFeignClient;
import com.atguigu.spzx.model.entity.h5.CartInfo;
import com.atguigu.spzx.model.entity.product.ProductSku;
import com.atguigu.spzx.model.entity.user.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    @Autowired
    ProductFeignClient productFeignClient;  // 通过OpenFeign远程调用商品微服务



    @Override
    public void deleteChecked() {
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        String cacheKey = getKey(userInfo.getId());
        List<Object> cartInfoJsonObjList = redisTemplate.opsForHash().values(cacheKey);
        if(!CollectionUtils.isEmpty(cartInfoJsonObjList)){
            cartInfoJsonObjList.stream().map((cartInfoJsonObj)->JSON.parseObject(cartInfoJsonObj.toString(),CartInfo.class))
                    .filter(cartInfo -> cartInfo.getIsChecked()==1)
                    .forEach(cartInfo->redisTemplate.opsForHash().delete(cacheKey,String.valueOf(cartInfo.getSkuId())));
        }
    }


    @Override
    public List<CartInfo> getAllCkecked() {
        //把购物车中所有商品都获取出来
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        String cacheKey = getKey(userInfo.getId());
        List<Object> cartInfoJsonObjList = redisTemplate.opsForHash().values(cacheKey);

        //过滤出打钩购物项集合
        if(cartInfoJsonObjList!=null){
            return cartInfoJsonObjList.stream().map(cartInfoJsonObj-> JSON.parseObject(cartInfoJsonObj.toString(),CartInfo.class))
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1).collect(Collectors.toList());
        }

        return new ArrayList<>();
    }

    @Override
    public void clearCart() {
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        String cacheKey = getKey(userInfo.getId());
        redisTemplate.delete(cacheKey);
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        String cacheKey = getKey(userInfo.getId());
        List<Object> values = redisTemplate.opsForHash().values(cacheKey);
        List<CartInfo> cartInfoList = values.stream()
                .map((cartInfoJsonObj) -> JSON.parseObject(cartInfoJsonObj.toString(), CartInfo.class))
                .collect(Collectors.toList());
        for (CartInfo cartInfo : cartInfoList) {
            cartInfo.setIsChecked(isChecked);
            redisTemplate.opsForHash().put(cacheKey, String.valueOf(cartInfo.getSkuId()), JSON.toJSONString(cartInfo));
        }
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        String cacheKey = getKey(userInfo.getId());

//        String cartInfoJson2 = (String)redisTemplate.opsForHash().get(cacheKey, String.valueOf(skuId));
//        System.out.println("cartInfoJson2 = "+cartInfoJson2);
        String cartInfoJson = redisTemplate.opsForHash().get(cacheKey, String.valueOf(skuId)).toString();
        //System.out.println("cartInfoJson = "+cartInfoJson);

        if (StringUtils.hasText(cartInfoJson)) {
            CartInfo cartInfo = JSON.parseObject(cartInfoJson, CartInfo.class);
            cartInfo.setIsChecked(isChecked);
            redisTemplate.opsForHash().put(cacheKey, String.valueOf(skuId), JSON.toJSONString(cartInfo));
        }
    }

    @Override
    public void deleteCart(Long skuId) {
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        String cacheKey = getKey(userInfo.getId());
        redisTemplate.opsForHash().delete(cacheKey, String.valueOf(skuId));
    }

    @Override
    public List<CartInfo> getCartList() {
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        String cacheKey = getKey(userInfo.getId());
        List<Object> cartInfoListJson = redisTemplate.opsForHash().values(cacheKey);
        return cartInfoListJson.stream().map((cartInfoJson) -> JSON.parseObject(cartInfoJson.toString(), CartInfo.class))
                .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                .collect(Collectors.toList());

    }

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        //1.获取用户id
        String cacheKey = getKey(userInfo.getId());

        CartInfo cartInfo = null;
        //2.1 需要考虑添加购物车时，首次添加该商品，还是继续添加该商品（加 - 减）
        Object cartInfoJson = redisTemplate.opsForHash().get(cacheKey, String.valueOf(skuId));
        if (cartInfoJson != null) { //存在，修改数量
            cartInfo = JSON.parseObject(cartInfoJson.toString(), CartInfo.class);
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());

        } else { //不存在，直接添加新商品
            //2.封装购物车数据
            cartInfo = new CartInfo();
            // 购物车数据是从商品详情得到 {skuInfo}
            ProductSku productSku = productFeignClient.getBySkuId(skuId);
            cartInfo.setUserId(userInfo.getId());
            cartInfo.setSkuId(skuId);
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setImgUrl(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());

        }
        //添加购物车
        redisTemplate.opsForHash().put(cacheKey, String.valueOf(skuId), JSON.toJSONString(cartInfo));
    }

    private String getKey(Long userInfoId) {
        return "userInfo:cart:" + userInfoId;
    }


}
